package com.feixiang.springbootinit.service.impl;
import cn.hutool.core.date.DateUtil;
import com.feixiang.springbootinit.common.ErrorCode;
import com.feixiang.springbootinit.exception.BusinessException;
import com.feixiang.springbootinit.service.FileStorageService;
import com.feixiang.springbootinit.utils.SessionArchiveUtil;
import com.feixiang.springbootinit.utils.VoiceUtil; // 引入自定义工具类
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.Date;

/**
 * 本地文件存储实现（集成VoiceUtil实现AMR转MP3）
 */
@Service
@Slf4j
public class LocalFileStorageServiceImpl implements FileStorageService {

    @Value("${file-upload-path.win}")
    private String fileUploadPath;

    @Value("${file-mapping-url.win}")
    private String fileMappingUrl;

    @Override
    public String storeFile(long sdk, String sdkFileId, String md5Sum, String fileExt, String subDir) throws Exception {
        // 目标格式：如果原始是AMR，则转为MP3；否则保持原格式
        boolean needConvert = "amr".equalsIgnoreCase(fileExt);
        String targetExt = needConvert ? "mp3" : fileExt;
        // 检查目标文件是否已存在（避免重复转换和存储）
        if (isFileExists(md5Sum, targetExt, subDir)) {
            log.info("目标文件已存在，直接返回路径：{}", md5Sum);
            return getExistingFilePath(md5Sum, targetExt, subDir);
        }
        // 1. 构建存储目录（根目录/子目录/日期目录，如：upload/voice/2025/0805/）
        String dateDir = DateUtil.format(new Date(), "yyyy/MMdd");
        String fullDir = fileUploadPath + File.separator + subDir + File.separator + dateDir;
        File dir = new File(fullDir);
        if (!dir.exists() && !dir.mkdirs()) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "创建文件目录失败：" + fullDir);
        }
        // 2. 下载原始文件（AMR格式）
        String sourceFileName = md5Sum + "." + fileExt; // 原始文件名（带AMR扩展名）
        String sourceFilePath = fullDir + File.separator + sourceFileName;
        // 调用企微SDK下载文件到本地
        SessionArchiveUtil.GetMediaData(sdk, sdkFileId, null, null, 1000L, sourceFilePath);
        log.info("原始文件下载成功：{}", sourceFilePath);
        // 3. 如果需要转换，调用VoiceUtil转换为MP3
        String targetFilePath;
        if (needConvert) {
            String targetFileName = md5Sum + "." + targetExt; // 目标文件名（带MP3扩展名）
            targetFilePath = fullDir + File.separator + targetFileName;
            // 调用自定义工具类进行格式转换（AMR -> MP3）
            VoiceUtil.audioFormatConversion(
                    new File(sourceFilePath), // 源文件
                    new File(targetFilePath), // 目标文件
                    targetExt // 目标格式（mp3）
            );
            log.info("AMR转MP3成功：{}", targetFilePath);
            // 转换完成后删除原始AMR文件，节省空间
            if (!new File(sourceFilePath).delete()) {
                log.warn("删除原始AMR文件失败：{}", sourceFilePath);
            }
        } else {
            // 无需转换，直接使用原始文件路径
            targetFilePath = sourceFilePath;
        }
        // 4. 返回目标文件的相对路径（用于生成访问URL）
        String targetFileName = md5Sum + "." + targetExt;
        return getRelativePath(subDir, dateDir, targetFileName);
    }

    // 以下方法保持不变（复用原有逻辑）
    @Override
    public String getFileUrl(String storedPath) {
        return "/" + storedPath;
    }

    @Override
    public boolean isFileExists(String md5Sum, String fileExt, String subDir) {
        String dateDir = DateUtil.format(new Date(), "yyyy/MMdd");
        String relativePath = getRelativePath(subDir, dateDir, md5Sum + "." + fileExt);
        String fullPath = fileUploadPath + File.separator + relativePath;
        return new File(fullPath).exists();
    }

    @Override
    public boolean deleteFile(String storedPath) {
        String fullPath = fileUploadPath + File.separator + storedPath;
        File file = new File(fullPath);
        return file.exists() && file.delete();
    }

    private String getRelativePath(String subDir, String dateDir, String fileName) {
        return subDir + "/" + dateDir + "/" + fileName;
    }

    private String getExistingFilePath(String md5Sum, String fileExt, String subDir) {
        String dateDir = DateUtil.format(new Date(), "yyyy/MMdd");
        return getRelativePath(subDir, dateDir, md5Sum + "." + fileExt);
    }
}